package main

import (
	"fmt"
	"github.com/cppdebug/windev"
	"math/rand"
	"os"
	"os/exec"
	"sync"
	"time"
)

const (
	TRANSVERSE  int    = 20  //地图横向单位量
	PORTRAIT    int    = 20  //地图竖向单位量
	MAP_ELEMENT string = "▓" //构成地图的基本图形
	START       string = "○" //开始位置
	END         string = "□" //结束位置
)

var (
	sign           = map[string]string{"up": "↑", "down": "↓", "left": "←", "right": "→"} //路径标记
	randSeek int64 = 1
	l        sync.Mutex
)

/*
	地图
*/
type Maps struct {
	MapSlice [][]string //地图构造切片
	Start    []int      //开始坐标
	End      []int      //结束坐标
	Nowz     []int      //当前坐标位置
}

/*
\	绘制地图
*/
func (this *Maps) DrawMap() {
	for _, v1 := range this.MapSlice {
		for _, v2 := range v1 {
			fmt.Printf("%s", v2)
		}
		fmt.Printf("\r\n")
	}
}

/*
	初始化地图数据
*/
func (this *Maps) Initialization() {
	for h := 0; h < PORTRAIT; h++ {
		this.MapSlice = append(this.MapSlice, []string{})
		for w := 0; w < TRANSVERSE; w++ {
			this.MapSlice[h] = append(this.MapSlice[h], MAP_ELEMENT)
		}
	}
	this.MapSlice[this.Start[0]][this.Start[1]] = START //设置入口
	this.MapSlice[this.End[0]][this.End[1]] = END       //设置出口
}

/*
	获取随机数
*/
func Random(rint int) int {
	r := rand.New(rand.NewSource(getRandSeek()))
	return r.Intn(rint)
}

func getRandSeek() int64 {
	l.Lock()
	if randSeek >= 100000000 {
		randSeek = 1
	}
	randSeek++
	l.Unlock()
	return time.Now().UnixNano() + randSeek
}

/*
	获取随机坐标
*/
func RandomCoordinate() []int {
	rdata := []int{}
	num := Random(4)
	switch num {
	case 0: //h=0 w=1-9 	地图上边缘
		rdata = append(rdata, 0, Random(TRANSVERSE))
	case 1: //h=9 w=1-9 地图下边缘
		rdata = append(rdata, PORTRAIT-1, Random(TRANSVERSE))
	case 2: //h=1-9 w=0 地图左边缘
		rdata = append(rdata, Random(PORTRAIT), 0)
	case 3: //h=1-9 w=9
		rdata = append(rdata, Random(PORTRAIT), TRANSVERSE-1)
	default:
		rdata = append(rdata, Random(PORTRAIT), 0)
	}
	return rdata //[h,w]
}

/*
	清除图像
*/
func (this *Maps) Cls() {
	cmd := exec.Command("cmd", "/c", "cls")
	cmd.Stdout = os.Stdout
	cmd.Run()
}

/**
查看是否可以移动
*/
func CheckIsRemove(maps *Maps, direction string) int {
	var nexNowz = []int{0,0}
	switch direction {
	case "up":
		if maps.Nowz[0] == 0 {
			return 0;
		}
		nexNowz = []int{maps.Nowz[0] - 1, maps.Nowz[1]}
	case "down":
		if maps.Nowz[0] == PORTRAIT-1 {
			return 0;
		}
		nexNowz = []int{maps.Nowz[0] + 1, maps.Nowz[1]}

	case "left":
		if maps.Nowz[1] == 0 {
			return 0;
		}
		nexNowz = []int{maps.Nowz[0], maps.Nowz[1] - 1}
	case "right":
		if maps.Nowz[1] == TRANSVERSE-1 {
			return 0;
		}
		nexNowz = []int{maps.Nowz[0], maps.Nowz[1] + 1}
	}
	if maps.MapSlice[nexNowz[0]][nexNowz[1]] != MAP_ELEMENT && maps.MapSlice[nexNowz[0]][nexNowz[1]] != END{
		return 0
	}
	if maps.End[0] == nexNowz[0] && maps.End[1] == nexNowz[1] {
		maps.MapSlice[maps.Nowz[0]][maps.Nowz[1]] = sign[direction]
		maps.Nowz = nexNowz
		maps.MapSlice[nexNowz[0]][nexNowz[1]] = START
		return 2
	}
	maps.MapSlice[maps.Nowz[0]][maps.Nowz[1]] = sign[direction]
	maps.Nowz = nexNowz
	maps.MapSlice[nexNowz[0]][nexNowz[1]] = START
	return 1
}

func main() {
	START:
	start := RandomCoordinate()
	end := RandomCoordinate()

	if end[0] == start[0] && end[1] == start[1] {
		main()
	}
	maps := Maps{[][]string{}, start, end, start}
	maps.Initialization() //初始化地图参数
	maps.DrawMap()	//绘制地图
	for {
		var direction string
		switch {
		case windev.KeyDownUp(windev.VK_ESCAPE) == 1:
			fmt.Println("退出游戏!")
			os.Exit(1)
		case windev.KeyDownUp(windev.VK_UP) == 1:
			direction = "up"
		case windev.KeyDownUp(windev.VK_DOWN) == 1:
			direction = "down"
		case windev.KeyDownUp(windev.VK_LEFT) == 1:
			direction = "left"
		case windev.KeyDownUp(windev.VK_RIGHT) == 1:
			direction = "right"
		}
		if direction != ""{
			r := CheckIsRemove(&maps, direction)
			if r == 1 {
				maps.Cls()
				maps.DrawMap()
			} else if (r == 2) {
				maps.Cls()
				maps.DrawMap()
				goto END
			}
		}
		time.Sleep(time.Millisecond * 10)
	}
END:
	fmt.Println("游戏结束!")
	maps.Cls()
	goto START
}
